package com.fadis.persist;

import com.fadis.FadisLog;
import com.fadis.cmd.CmdDispatcher;
import com.fadis.FadisThread;

import java.io.File;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * aof持久化 Append-Only-File
 * 写运行在单独一个线程
 * 读运行在redis线程
 */
public class AOFMgmr {

    public static volatile boolean isRestoring = false;

    private static AOFLogProvider provider = new FileLogProvider("/Users/cowthan/Documents/upload-bed/aof.log");

    public static void setAOFLogProvider(AOFLogProvider provider){
        AOFMgmr.provider = provider;
    }

    /**
     * save("set", "*3\r\b$3set....")
     * @param cmd
     * @param log
     */
    public static void save(String cmd, String log){
        if(isRestoring) return;
        FadisThread.runInAofThread(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
//                FadisLog.log("AOF: 写入" + log.replace("\r\n", "/r/n"));
                provider.write(cmd, log);
                return null;
            }
        });
    }

    public static void restoreFromLog(){

        FadisThread.runInRedisThread(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                isRestoring = true;
                System.out.println("~~ AOF restore 开启 --------");
                List<String> list = provider.read();
                int len = list == null ? 0 : list.size();
                for (int i = 0; i < len; i++) {
                    System.out.println("恢复：" + list.get(i).replace("\r\n", "/r/n"));
                    CmdDispatcher.runInCurrentThread(list.get(i));
                }
                isRestoring = false;
                System.out.println("~~ AOF restore 结束 --------");
                return null;
            }
        });
    }

    public static List<String>  getLogs(){
        List<String> list = provider.read();
        return list;
    }

    public static void main(String[] args) {
        new File("/Users/cowthan/Documents/upload-bed/aof.log").delete();

        AOFMgmr.save("set", "*3\r\nset\r\n$aa&a\r\n$2x9\r\n");
        AOFMgmr.save("set", "*3\r\nset\r\n$aa&a\r\n$2x9\r\n");
        AOFMgmr.save("get", "a");
        AOFMgmr.save("ttt", "1234");

        List<String> list = AOFMgmr.getLogs();
//        System.out.println(JsonUtils.toJsonPretty(list));
    }

}
